
import UIKit

public enum AnimationType: Int {
    case fade = 1                   //淡入淡出 --Default
    case push                       //推挤
    case reveal                     //揭开
    case moveIn                     //覆盖
    case cube                       //立方体
    case suckEffect                 //吮吸
    case oglFlip                    //翻转
    case rippleEffect               //波纹
    case pageCurl                   //翻页
    case pageUnCurl                 //反翻页
    case cameraIrisHollowOpen       //开镜头
    case cameraIrisHollowClose      //关镜头
    case curlDown                   //下翻页
    case curlUp                     //上翻页
    case flipFromLeft               //左翻转
    case flipFromRight              //右翻转
}

public enum AnimationDirection: Int {
    case top, left, bottom, right
}

public class RLAnimation: NSObject {
    
    static let DEFAULT_ANIMATION_DURATION: Float = 0.5
    static let DEFAULT_ANIMATION_DIRECTION: AnimationDirection = .top
    static let DEFAULT_ANIMATION_TYPE: AnimationType = .fade
    
    public class func animation(_ view: UIView) {
        RLAnimation().startAnimationWith(view,
                                         type: RLAnimation.DEFAULT_ANIMATION_TYPE,
                                         direction: RLAnimation.DEFAULT_ANIMATION_DIRECTION,
                                         duration: RLAnimation.DEFAULT_ANIMATION_DURATION)
    }
    
    public class func animation(_ view: UIView, duration: Float) {
        RLAnimation().startAnimationWith(view,
                                         type: RLAnimation.DEFAULT_ANIMATION_TYPE,
                                         direction: RLAnimation.DEFAULT_ANIMATION_DIRECTION,
                                         duration: duration)
    }
    
    public class func animation(_ view: UIView, type: AnimationType) {
        RLAnimation().startAnimationWith(view,
                                         type: type,
                                         direction: RLAnimation.DEFAULT_ANIMATION_DIRECTION,
                                         duration: RLAnimation.DEFAULT_ANIMATION_DURATION)
    }
    
    public class func animation(_ view: UIView, type: AnimationType, duration: Float) {
        RLAnimation().startAnimationWith(view,
                                         type: type,
                                         direction: RLAnimation.DEFAULT_ANIMATION_DIRECTION,
                                         duration: duration)
    }
    
    public class func animation(_ view: UIView, type: AnimationType, direction: AnimationDirection) {
        RLAnimation().startAnimationWith(view,
                                         type: type,
                                         direction: direction,
                                         duration: RLAnimation.DEFAULT_ANIMATION_DURATION)
    }
    
    public class func animation(_ view: UIView, type: AnimationType, direction: AnimationDirection, duration: Float) {
        RLAnimation().startAnimationWith(view,
                                         type: type,
                                         direction: direction,
                                         duration: duration)
    }
    
    private func startAnimationWith(_ view: UIView, type: AnimationType, direction: AnimationDirection, duration: Float) {
        
        var animationDirection: String?
        
        switch direction {
        case .top:
            animationDirection = CATransitionSubtype.fromTop.rawValue
        case .left:
            animationDirection = CATransitionSubtype.fromLeft.rawValue
        case .bottom:
            animationDirection = CATransitionSubtype.fromBottom.rawValue
        case .right:
            animationDirection = CATransitionSubtype.fromRight.rawValue
        }
        
        switch type {
        case .fade:
            transition(with: CATransitionType.fade.rawValue, with: animationDirection, duration: TimeInterval(duration), for: view)
        case .push:
            transition(with: CATransitionType.push.rawValue, with: animationDirection, duration: TimeInterval(duration), for: view)
        case .reveal:
            transition(with: CATransitionType.reveal.rawValue, with: animationDirection, duration: TimeInterval(duration), for: view)
        case .moveIn:
            transition(with: CATransitionType.moveIn.rawValue, with: animationDirection, duration: TimeInterval(duration), for: view)
        case .cube:
            transition(with: "cube", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .suckEffect:
            transition(with: "suckEffect", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .oglFlip:
            transition(with: "oglFlip", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .rippleEffect:
            transition(with: "rippleEffect", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .pageCurl:
            transition(with: "pageCurl", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .pageUnCurl:
            transition(with: "pageUnCurl", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .cameraIrisHollowOpen:
            transition(with: "cameraIrisHollowOpen", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .cameraIrisHollowClose:
            transition(with: "cameraIrisHollowClose", with: animationDirection, duration: TimeInterval(duration), for: view)
        case .curlDown:
            animation(with: view, withAnimation: .curlDown, duration: TimeInterval(duration))
        case .curlUp:
            animation(with: view, withAnimation: .curlUp, duration: TimeInterval(duration))
        case .flipFromLeft:
            animation(with: view, withAnimation: .flipFromLeft, duration: TimeInterval(duration))
        case .flipFromRight:
            animation(with: view, withAnimation: .flipFromRight, duration: TimeInterval(duration))
        }
    }
}


// MARK: Animation

extension RLAnimation {
    
    func animation(with view: UIView, withAnimation transition: UIView.AnimationTransition, duration: TimeInterval) {
        UIView.animate(withDuration: duration) {
            UIView.setAnimationCurve(.easeInOut)
            UIView.setAnimationTransition(transition, for: view, cache: true)
        }
    }
    
    func transition(with type: String, with direction: String?, duration: TimeInterval, for view: UIView) {
        
        let animation = CATransition()
        
        animation.duration = duration
        animation.type = CATransitionType(rawValue: type)
        
        if let d = direction {
            animation.subtype = CATransitionSubtype(rawValue: d)
        }
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        
        view.layer.add(animation, forKey: "animation")
        
    }
    
}





